﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Autodesk.Revit.DB;
using YArchitech.LIB;
using YJKRevitBase.StringUtility;
using YJKRevitBase.StringUtility.FuzzySearchSuite;
using YJKGeometryFuncs;
using Teigha.TD;

namespace YJKPretreatmentModeling
{
	internal class DrawingTextDistinguish
	{
		public DrawingTextDistinguish(List<TextInfo> lstTextInfo)
		{
			this.m_lstTextInfo = lstTextInfo;
			this.initDataByXML();
		}

		public bool GetDrawingNameInFrame(out string strName, XYZ ptRectMin, XYZ ptRectMax)
		{
			strName = string.Empty;
			try
			{
				new List<OdDbText>();
				if (this.m_lstTextInfo.IsEmpty<TextInfo>() || this.m_lstItemKeyWord.IsEmpty<string>())
				{
					return false;
				}
				List<ISearchItem> list = this.PreTextToSearch(ptRectMin, ptRectMax);
				if (list.IsEmpty<ISearchItem>())
				{
					return false;
				}
				Dictionary<string, List<ISearchItem>> itemByKeyWord = this.GetItemByKeyWord(list);
				if (itemByKeyWord.IsEmpty<KeyValuePair<string, List<ISearchItem>>>())
				{
					return false;
				}
				foreach (KeyValuePair<string, List<ISearchItem>> keyValuePair in itemByKeyWord)
				{
					foreach (ISearchItem searchItem in keyValuePair.Value)
					{
						TextInfo textInfo = searchItem as TextInfo;
						if (textInfo != null && this.GetContentForItem(out strName, textInfo, list))
						{
							return true;
						}
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return false;
		}

		private List<ISearchItem> PreTextToSearch(XYZ ptRectMin, XYZ ptRectMax)
		{
			List<ISearchItem> list = new List<ISearchItem>();
			foreach (TextInfo textInfo in this.m_lstTextInfo)
			{
				if (Geometry.Greaterthan_Or_Equal(textInfo.Positon.x, ptRectMin.X) && Geometry.Greaterthan_Or_Equal(textInfo.Positon.y, ptRectMin.Y) && Geometry.Lessthan_Or_Equal(textInfo.Positon.x, ptRectMax.X) && Geometry.Lessthan_Or_Equal(textInfo.Positon.y, ptRectMax.Y))
				{
					string itemName = textInfo.ItemName;
					if ((this.m_nTextMaxLen <= 0 || itemName.Length <= this.m_nTextMaxLen) && (this.m_nTextMinLen <= 0 || itemName.Length >= this.m_nTextMinLen))
					{
						textInfo.CenterDisToFrame = new List<double>
						{
							Math.Abs(textInfo.Center.x - ptRectMin.X),
							Math.Abs(textInfo.Center.x - ptRectMax.X),
							Math.Abs(textInfo.Center.y - ptRectMin.Y),
							Math.Abs(textInfo.Center.y - ptRectMax.Y)
						}.Min();
						list.Add(textInfo);
					}
				}
			}
			return list;
		}

		private Dictionary<string, List<ISearchItem>> GetItemByKeyWord(List<ISearchItem> lstSearchItem)
		{
			Dictionary<string, List<ISearchItem>> dictionary = new Dictionary<string, List<ISearchItem>>();
			FuzzySearchManger fuzzySearchManger = new FuzzySearchManger(lstSearchItem, false, true, 50);
			int num = this.m_lstItemKeyWord.Max((string item) => StringUtilityMethod.RemoveSpace(item).Length);
			foreach (string text in this.m_lstItemKeyWord)
			{
				if (!dictionary.Keys.Contains(text))
				{
					List<ISearchItem> list = fuzzySearchManger.Search(text);
					foreach (ISearchItem searchItem in list)
					{
						if (StringUtilityMethod.RemoveSpace(searchItem.ItemName).Length < num * 2 && !list.Contains(searchItem))
						{
							list.Add(searchItem);
						}
					}
					if (!list.IsEmpty<ISearchItem>())
					{
						list.Sort(delegate(ISearchItem itemX, ISearchItem itemY)
						{
							TextInfo textInfo = itemX as TextInfo;
							TextInfo textInfo2 = itemY as TextInfo;
							if (Geometry.LessThan(textInfo.CenterDisToFrame, textInfo2.CenterDisToFrame, 0.0001))
							{
								return -1;
							}
							if (Geometry.IsEqual(textInfo.CenterDisToFrame, textInfo2.CenterDisToFrame, 0.0001))
							{
								return 0;
							}
							return 1;
						});
						dictionary.Add(text, list);
					}
				}
			}
			return dictionary;
		}

		private bool GetContentForItem(out string strName, TextInfo textInfoItem, List<ISearchItem> lstSearch)
		{
			strName = string.Empty;
			double val = Math.Max(textInfoItem.Height, textInfoItem.Width) * this.m_dItemAreaTimes;
			List<ISearchItem> list = new List<ISearchItem>();
			list.AddRange(lstSearch);
			FuzzySearchManger fuzzySearchManger = new FuzzySearchManger(lstSearch, false, true, 50);
			foreach (string input in this.m_lstIgnoreWord)
			{
				foreach (ISearchItem item in fuzzySearchManger.Search(input))
				{
					list.Remove(item);
				}
			}
			List<ISearchItem> list2 = new List<ISearchItem>();
			for (int i = 0; i < list.Count; i++)
			{
				TextInfo textInfo = list[i] as TextInfo;
				double val2 = textInfo.Center.distanceTo(textInfoItem.Center);
				if (!Geometry.IsEqual(val2, 0.0, 0.0001) && !Geometry.GreaterThan(val2, val) && textInfo.Text.objectId() != textInfoItem.Text.objectId())
				{
					list2.Add(textInfo);
				}
			}
			Dictionary<TextInfo, RefInfo> dicTextRefInfo = new Dictionary<TextInfo, RefInfo>();
			foreach (ISearchItem searchItem in list2)
			{
				TextInfo textInfo2 = searchItem as TextInfo;
				double dPosDis = textInfo2.Positon.distanceTo(textInfoItem.Positon);
				double dCenterDis = textInfo2.Center.distanceTo(textInfoItem.Center);
				XYZ xyz = Geometry.RotateTo(new XYZ(textInfo2.Center.x - textInfoItem.Positon.x, textInfo2.Center.y - textInfoItem.Positon.y, 0.0).Normalize(), -(textInfoItem.ActualRotation + textInfoItem.FontRotation), XYZ.BasisZ);
				double num = xyz.AngleTo(XYZ.BasisX);
				if (Geometry.GreaterThan(xyz.Y, 0.0))
				{
					num = Math.PI*2 - num;
				}
				double num2 = this.m_dStartAngle / 180.0 * Math.PI;
				double num3 = this.m_dEndAngle / 180.0 * Math.PI;
				if (num >= num2 && (num <= num3 || num >= num2 + Math.PI*2))
				{
					double num4 = textInfoItem.ActualRotation + textInfoItem.FontRotation;
					double num5 = textInfo2.ActualRotation - num4;
					if (Geometry.LessThan(num5, 0.0))
					{
						num5 = -1.0 * num5;
					}
					else if (Geometry.GreaterThan(num5, 0.0))
					{
						num5 = Math.PI*2 - num5;
					}
					bool bEndWithSpecialChar = textInfo2.ItemName.EndsWith("图");
					RefInfo value = new RefInfo(num, num5, dPosDis, dCenterDis, bEndWithSpecialChar, textInfo2.Depth);
					dicTextRefInfo.Add(textInfo2, value);
				}
			}
			if (dicTextRefInfo.IsEmpty<KeyValuePair<TextInfo, RefInfo>>())
			{
				return false;
			}
			List<TextInfo> list3 = dicTextRefInfo.Keys.ToList<TextInfo>();
			list3.Sort(delegate(TextInfo x, TextInfo y)
			{
				RefInfo refInfo = dicTextRefInfo[x];
				RefInfo refInfo2 = dicTextRefInfo[y];
				if (refInfo.Depth < refInfo2.Depth)
				{
					return -1;
				}
				if (refInfo.Depth > refInfo2.Depth)
				{
					return 1;
				}
				double num6 = this.m_dStartAngle / 180.0 * Math.PI;
				double num7 = this.m_dEndAngle / 180.0;
				double num8 = refInfo.PosAngle - num6;
				if (num8 > Math.PI*2)
				{
					num8 -= Math.PI*2;
				}
				double num9 = refInfo2.PosAngle - num6;
				if (num9 > Math.PI*2)
				{
					num9 -= Math.PI*2;
				}
				if (refInfo.EndWithSpecialChar && !refInfo2.EndWithSpecialChar)
				{
					return -1;
				}
				if (!refInfo.EndWithSpecialChar && refInfo2.EndWithSpecialChar)
				{
					return 1;
				}
				if (Geometry.LessThan(refInfo.CenterDis, refInfo2.CenterDis, Math.Max(refInfo.CenterDis, refInfo2.CenterDis) / 3.0))
				{
					return -1;
				}
				if (Geometry.LessThan(num8, num9))
				{
					return -1;
				}
				return 1;
			});
			strName = list3[0].ItemName;
			return true;
		}

		private void initDataByXML()
		{
			XElement xelement = XDocument.Load(Product.DataLocation + "\\PretreatmentModeling\\DrawingTextDistinguish.xml").Element("DrawingTextDistinguish");
			XElement xelement2 = xelement.Element("TextLenLimit");
			string value = xelement2.Attribute("Min").Value;
			string value2 = xelement2.Attribute("Max").Value;
			int.TryParse(value, out this.m_nTextMinLen);
			int.TryParse(value2, out this.m_nTextMaxLen);
			foreach (XElement xelement3 in xelement.Element("ItemKeyWords").Elements("ItemKeyWord").ToList<XElement>())
			{
				string value3 = xelement3.Attribute("text").Value;
				this.m_lstItemKeyWord.Add(value3);
			}
			foreach (XElement xelement4 in xelement.Element("ContentIgnoreKeyWords").Elements("ContentIgnoreKeyWord").ToList<XElement>())
			{
				string value4 = xelement4.Attribute("text").Value;
				this.m_lstIgnoreWord.Add(value4);
			}
			XElement xelement5 = xelement.Element("ReferenceParameter");
			double.TryParse(xelement5.Element("ItemAreaTimes").Attribute("times").Value, out this.m_dItemAreaTimes);
			XElement xelement6 = xelement5.Element("Angle");
			double.TryParse(xelement6.Attribute("start").Value, out this.m_dStartAngle);
			double.TryParse(xelement6.Attribute("end").Value, out this.m_dEndAngle);
		}

		private List<TextInfo> m_lstTextInfo = new List<TextInfo>();

		private List<string> m_lstItemKeyWord = new List<string>();

		private List<string> m_lstIgnoreWord = new List<string>();

		private int m_nTextMinLen = -1;

		private int m_nTextMaxLen = -1;

		private double m_dItemAreaTimes = 10.0;

		private double m_dStartAngle = -15.0;

		private double m_dEndAngle = 105.0;
	}
}
